/*
 * Copyright (c) 2007-2008, Thomas Krause (tho.krause@gmail.com)
 * 
 * All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 * 
 *     * Redistributions of source code must retain the above copyright notice,
 *       this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright notice,
 *       this list of conditions and the following disclaimer in the documentation
 *       and/or other materials provided with the distribution.
 *     * Neither the name of gidoo nor the names of its contributors may be used to
 *       endorse or promote products derived from this software without specific
 *       prior written permission.
 * 
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

package org.gidoo.cms.editor;

import org.gidoo.cms.RedirectPage;
import org.gidoo.cms.editor.edit.EditPanel;
import org.gidoo.cms.editor.history.HistoryPanel;
import org.gidoo.cms.login.GidooCMSAuthenticatedWebSession;
import java.util.LinkedList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeNode;
import org.apache.wicket.Component;
import org.apache.wicket.authorization.strategies.role.annotations.AuthorizeInstantiation;
import org.apache.wicket.behavior.HeaderContributor;
import org.apache.wicket.extensions.ajax.markup.html.tabs.AjaxTabbedPanel;
import org.apache.wicket.extensions.markup.html.tabs.AbstractTab;
import org.apache.wicket.markup.html.WebPage;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.link.Link;
import org.apache.wicket.markup.html.panel.FeedbackPanel;
import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.markup.html.tree.BaseTree;
import org.apache.wicket.markup.html.tree.ITreeStateListener;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.Model;
import org.gidoo.cms.GidooCMS;
import org.gidoo.cms.admin.AdminPage;
import org.gidoo.cms.data.CMSSection;
import org.gidoo.cms.data.Folder;
import org.gidoo.cms.dbconnection.DatabaseConnectionException;
import org.gidoo.cms.editor.resources.ResourcesPanel;
import org.gidoo.cms.editor.structure.StructurePanel;
import org.gidoo.cms.editor.view.CodeViewPanel;
import org.gidoo.wickettools.WicketTools;
import org.gidoo.wickettools.xmledit.XMLEditor;

/**
 *
 * @author thomas
 */
@AuthorizeInstantiation(GidooCMSAuthenticatedWebSession.ROLE_EDITOR)
public class EditorPage extends WebPage implements ITreeStateListener
{ 
  
  Label lblTitle;
  Link lnkLogout;
  
  BaseTree treeNav;
  DefaultTreeModel treeNavModel;
  
  DefaultMutableTreeNode root;
  
  AjaxTabbedPanel panelTabs;
  
  FeedbackPanel feedbackPanel;
  
  Folder currentSelectedFolder;
  
  EditPanel theEditPanel;
  HistoryPanel theHistoryPanel;
  ResourcesPanel theResourcesPanel;
  StructurePanel theStructurePanel;
  CodeViewPanel theCodeViewPanel;
  
  private long lastCutID = -1;
  
  
  /** Creates a new instance of EditorPage */
  public EditorPage()
  {
    add(HeaderContributor.forCss(AdminPage.CSS_ADMIN));
    add(HeaderContributor.forCss(XMLEditor.CSS_EDITOR));
    
    currentSelectedFolder = null;
    final EditorPage thePage = this;
   
    feedbackPanel= new FeedbackPanel("feedbackPanel");
    feedbackPanel.setOutputMarkupId(true);
    add(feedbackPanel);
    
    lblTitle = new Label("lblTitle", new Model(getString("editorPage")));
    lnkLogout = new Link("lnkLogout")
    {
      public void onClick()
      {
        GidooCMSAuthenticatedWebSession s = (GidooCMSAuthenticatedWebSession) this.getSession();
        s.signOut();
        setResponsePage(RedirectPage.class);
      }
    };
    
    add(lnkLogout);
    
    add(new Link("lnkRefresh") {
      @Override
      public void onClick()
      {
        thePage.updateDataAndView();
        setResponsePage(thePage);
      }
    });
    
    add(lblTitle);
    
    createTree();
    
    List<AbstractTab> tabs = new LinkedList<AbstractTab>();

    tabs.add(new AbstractTab(new Model(getString("edit"))) {

      @Override
      public Panel getPanel(String panelId)
      {
        theEditPanel = new EditPanel(panelId, currentSelectedFolder, thePage);
        return theEditPanel;
      }
    });
    
    tabs.add(new AbstractTab(new Model(getString("view"))) {

      @Override
      public Panel getPanel(String panelId)
      {
        theCodeViewPanel = new CodeViewPanel(panelId, currentSelectedFolder);
        return theCodeViewPanel;
      }
    });

    tabs.add(new AbstractTab(new Model(getString("resources"))) {

      @Override
      public Panel getPanel(String panelId)
      {
        theResourcesPanel = new ResourcesPanel(panelId, currentSelectedFolder, thePage);
        return theResourcesPanel;
      }
    });
    
    tabs.add(new AbstractTab(new Model(getString("history"))) {

      @Override
      public Panel getPanel(String panelId)
      {
        theHistoryPanel = new HistoryPanel(panelId, currentSelectedFolder, thePage);
        return theHistoryPanel;
      }
    });

    tabs.add(new AbstractTab(new Model(getString("structure"))) {

      @Override
      public Panel getPanel(String panelId)
      {
        theStructurePanel = new StructurePanel(panelId, currentSelectedFolder, thePage);
        return theStructurePanel;
      }
    });
    
    panelTabs = new AjaxTabbedPanel("panelTabs", tabs);
    panelTabs.setOutputMarkupId(true);  
    add(panelTabs);
    
  }
  
  private void createTree()
  {
    root = new DefaultMutableTreeNode("root");
    treeNavModel = new DefaultTreeModel(root);
    
    treeNav = new BaseTree("treeNav", new Model(treeNavModel))
    {
      protected Component newNodeComponent(String id, IModel model)
      { 
        return new EditorTreePanel(id, model, treeNav);
      }
      
    };
    
    treeNav.setRootLess(true);
    treeNav.getTreeState().addTreeStateListener(this);
    treeNav.getTreeState().collapseAll();
        
    updateTreeModel(null);
    
    add(treeNav);
    
  }
  
  public void updateDataAndView()
  {
    updateDataAndView(currentSelectedFolder);
  }
  
  public void updateDataAndView(Folder folderToSelect)
  {
    updateTreeModel(folderToSelect);
    if(theCodeViewPanel != null)
      theCodeViewPanel.updateDataAndView(currentSelectedFolder);
    if(theEditPanel != null)
      theEditPanel.updateDataAndView(currentSelectedFolder, this);
    if(theHistoryPanel != null)
      theHistoryPanel.updateDataAndView(currentSelectedFolder, this);
    if(theResourcesPanel != null)
      theResourcesPanel.updateDataAndView(currentSelectedFolder, this);
    // structures doesn't need any updates
  }
  
  private void updateTreeModel(Folder folderToSelect)
  {
    if(root != null)
    {
      root.removeAllChildren();
      
      try
      {
        GidooCMSAuthenticatedWebSession session = (GidooCMSAuthenticatedWebSession) getSession();
        List<CMSSection> sections = session.getUserInfo().getSections_edit();

        for(CMSSection s : sections)
        {
          DefaultMutableTreeNode sNode = new DefaultMutableTreeNode();
          sNode.setUserObject(s);
          root.add(sNode);
          Folder rootFolder = s.getRootFolder();
          if(rootFolder != null)
          {            
            populateFolder(rootFolder, sNode, folderToSelect);
            if(rootFolder.equals(folderToSelect) && treeNav != null)
            {
              treeNav.getTreeState().selectNode(sNode, true);
              treeNav.getTreeState().expandNode(sNode);
            }
          }
        }
        
        if(treeNavModel != null)
        {
          treeNavModel.reload();
        }
      }
      catch(Exception ex)
      {
        Logger.getLogger(EditorPage.class.getName()).log(Level.SEVERE, null, ex);
        error("error");
      }
    }
  }
  
  private void populateFolder(Folder parentFolder, DefaultMutableTreeNode parentNode, Folder folderToSelect)
  {
    try
    {
      List<Folder> children = ((GidooCMS) getApplication()).getDb().getChildrenOfFolder(parentFolder);
      if (children != null && parentNode != null)
      {
        for (Folder c : children)
        {
          DefaultMutableTreeNode n = new DefaultMutableTreeNode();
          n.setUserObject(c);
          parentNode.add(n);
          populateFolder(c, n, folderToSelect);
          if(c.equals(folderToSelect) && treeNav != null)
          {
            treeNav.getTreeState().selectNode(n, true);
            TreeNode nodeToExpand = n;
            while(nodeToExpand != null)
            {
              treeNav.getTreeState().expandNode(nodeToExpand);
              nodeToExpand = nodeToExpand.getParent();
            }
          }
        }
      }
    } catch (DatabaseConnectionException ex)
    {
      Logger.getLogger(EditorPage.class.getName()).log(Level.SEVERE, null, ex);
      error(getString("dberror"));
    }
  }
 
  public void allNodesCollapsed()
  {

    
  }

  public void allNodesExpanded()
  {
    
    
  }

  public void nodeCollapsed(TreeNode node)
  {
    
    
  }

  public void nodeExpanded(TreeNode node)
  {
    
    
  }

  public void nodeSelected(TreeNode node)
  {
    treeNav.getTreeState().expandNode(node);
    DefaultMutableTreeNode n = (DefaultMutableTreeNode) node;
    Object o = n.getUserObject();
    if(o instanceof Folder)
    {
      currentSelectedFolder = 
        (Folder) o;    
    }
    else if(o instanceof CMSSection)
    {
      try
      {
        currentSelectedFolder = ((CMSSection) o).getRootFolder();
      }
      catch (DatabaseConnectionException ex)
      {
        Logger.getLogger(EditorPage.class.getName()).log(Level.SEVERE, null, ex);
        error(getString("dberror"));
      }
    }
    else
    {
      currentSelectedFolder = null;
    }
    
    panelTabs.setSelectedTab(panelTabs.getSelectedTab());

    WicketTools.addToAjaxRequestTarget(new Component[] {feedbackPanel, panelTabs}, this);
    
  }

  public void nodeUnselected(TreeNode node)
  {
    currentSelectedFolder = null;
    panelTabs.setSelectedTab(panelTabs.getSelectedTab());
    
    WicketTools.addToAjaxRequestTarget(new Component[] {feedbackPanel, panelTabs}, this);
  }
  
  public Folder getCurrentSelectedFolder()
  {
    return currentSelectedFolder;
  }
 
  
  
  public BaseTree getTreeNav()
  {
    return treeNav;
  }

  public FeedbackPanel getFeedbackPanel()
  {
    return feedbackPanel;
  }

  public AjaxTabbedPanel getPanelTabs()
  {
    return panelTabs;
  }
  
  
  /** Get the ID of the last "cutted" page */
  public long getLastCutID()
  {
    return lastCutID;
  }

  /**Get the ID of the last "cutted" page */
  public void setLastCutID(long lastCutID)
  {
    this.lastCutID = lastCutID;
  }
  
}
